<?php

namespace Kateba\SiteBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Message
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Kateba\SiteBundle\Entity\MessageRepository")
 */
class Message {

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \Kateba\UserBundle\Entity\User
     *
     * @ORM\ManyToOne(targetEntity="\Kateba\UserBundle\Entity\User", inversedBy="messages")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
     */
    private $user;

    /**
     * @var string
     * @Assert\NotBlank
     * @ORM\Column(name="message", type="text")
     */
    private $message;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="createdAt", type="datetime")
     */
    private $createdAt;

    /**
     * @var boolean
     * if set to true then the admin is the one sent this message
     * @ORM\Column(name="isAdmin", type="boolean")
     */
    private $isAdmin = false;

    /**
     * @var boolean
     *
     * @ORM\Column(name="isNew", type="boolean")
     */
    private $isNew = true;

    public function __construct() {
        $this->createdAt = new \DateTime();
    }

    /**
     * @var string $attachment
     *
     * @ORM\Column(name="attachment", type="string", length=20, nullable=true)
     */
    private $attachment;

    /**
     * a temp variable for storing the old attachment name to delete the old attachment after the update
     * @var string $temp
     */
    private $temp;

    /**
     * @Assert\File(mimeTypes = {"application/msword", "application/pdf", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/rtf"})
     * @var \Symfony\Component\HttpFoundation\File\UploadedFile
     */
    private $file;

    /**
     * Set attachment
     *
     * @param string $attachment
     * @return $this
     */
    public function setAttachment($attachment) {
        $this->attachment = $attachment;
        return $this;
    }

    /**
     * Get attachment
     *
     * @return string
     */
    public function getAttachment() {
        return $this->attachment;
    }

    /**
     * Set file
     *
     * @param \Symfony\Component\HttpFoundation\File\UploadedFile $file
     * @return $this
     */
    public function setFile($file) {
        $this->file = $file;
        //check if we have an old attachment
        if ($this->attachment) {
            //store the old name to delete on the update
            $this->temp = $this->attachment;
            $this->attachment = NULL;
        } else {
            $this->attachment = 'initial';
        }
        return $this;
    }

    /**
     * Get file
     *
     * @return \Symfony\Component\HttpFoundation\File\UploadedFile
     */
    public function getFile() {
        return $this->file;
    }

    /**
     * this function is used to delete the current attachment
     * the deleting of the current object will also delete the attachment and you do not need to call this function
     * if you call this function before you remove the object the attachment will not be removed
     */
    public function removeAttachment() {
        //check if we have an old attachment
        if ($this->attachment) {
            //store the old name to delete on the update
            $this->temp = $this->attachment;
            //delete the current attachment
            $this->attachment = NULL;
        }
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function preUpload() {
        if (NULL !== $this->file && (NULL === $this->attachment || 'initial' === $this->attachment)) {
            //get the attachment extension
            $extension = $this->file->guessExtension();
            //generate a random attachment name
            $img = uniqid();
            //get the attachment upload directory
            $uploadDir = $this->getUploadRootDir();
            //check if the upload directory exists
            if (!@is_dir($uploadDir)) {
                //get the old umask
                $oldumask = umask(0);
                //not a directory probably the first time try to create the directory
                $success = @mkdir($uploadDir, 0755, TRUE);
                //reset the umask
                umask($oldumask);
                //check if we created the folder
                if (!$success) {
                    //could not create the folder throw an exception to stop the insert
                    throw new \Exception("Can not create the directory $uploadDir");
                }
            }
            //check that the file name does not exist
            while (@file_exists("$uploadDir/$img.$extension")) {
                //try to find a new unique name
                $img = uniqid();
            }
            //set the attachment new name
            $this->attachment = "$img.$extension";
        }
    }

    /**
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     */
    public function upload() {
        if (NULL !== $this->file) {
            // you must throw an exception here if the file cannot be moved
            // so that the entity is not persisted to the database
            // which the UploadedFile move() method does
            $this->file->move($this->getUploadRootDir(), $this->attachment);
            //remove the file as you do not need it any more
            $this->file = NULL;
        }
        //check if we have an old attachment
        if ($this->temp) {
            //try to delete the old attachment
            @unlink($this->getUploadRootDir() . '/' . $this->temp);
            //clear the temp attachment
            $this->temp = NULL;
        }
    }

    /**
     * @ORM\PostRemove()
     */
    public function postRemove() {
        //check if we have an attachment
        if ($this->attachment) {
            //try to delete the attachment
            @unlink($this->getAbsolutePath());
        }
    }

    /**
     * @return string the path of attachment starting of root
     */
    public function getAbsolutePath() {
        return $this->getUploadRootDir() . '/' . $this->attachment;
    }

    /**
     * @return string the relative path of attachment starting from web directory
     */
    public function getWebPath() {
        return NULL === $this->attachment ? NULL : '/' . $this->getUploadDir() . '/' . $this->attachment;
    }

    /**
     * @return string the path of upload directory starting of root
     */
    public function getUploadRootDir() {
        // the absolute directory path where uploaded documents should be saved
        return __DIR__ . '/../../../../web/' . $this->getUploadDir();
    }

    /**
     * @return string the document upload directory path starting from web folder
     */
    private function getUploadDir() {
        return 'uploads/messages-files';
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Set message
     *
     * @param string $message
     * @return Message
     */
    public function setMessage($message) {
        $this->message = $message;

        return $this;
    }

    /**
     * Get message
     *
     * @return string
     */
    public function getMessage() {
        return $this->message;
    }

    /**
     * Set createdAt
     *
     * @param \DateTime $createdAt
     * @return Message
     */
    public function setCreatedAt($createdAt) {
        $this->createdAt = $createdAt;

        return $this;
    }

    /**
     * Get createdAt
     *
     * @return \DateTime
     */
    public function getCreatedAt() {
        return $this->createdAt;
    }

    /**
     * Set isAdmin
     *
     * @param boolean $isAdmin
     * @return Message
     */
    public function setIsAdmin($isAdmin) {
        $this->isAdmin = $isAdmin;

        return $this;
    }

    /**
     * Get isAdmin
     *
     * @return boolean
     */
    public function getIsAdmin() {
        return $this->isAdmin;
    }

    /**
     * Set isNew
     *
     * @param boolean $isNew
     * @return Message
     */
    public function setIsNew($isNew) {
        $this->isNew = $isNew;

        return $this;
    }

    /**
     * Get isNew
     *
     * @return boolean
     */
    public function getIsNew() {
        return $this->isNew;
    }

    /**
     * Set user
     *
     * @param \Kateba\UserBundle\Entity\User $user
     * @return Message
     */
    public function setUser(\Kateba\UserBundle\Entity\User $user) {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \Kateba\UserBundle\Entity\User
     */
    public function getUser() {
        return $this->user;
    }

    /**
     * @author Mahmoud
     * @return string
     */
    public function getFileType() {
        if (strstr($this->attachment, '.pdf')) {
            return 'pdf';
        }
        return 'word';
    }

}